package utils.reflect;

import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

import utils.test.Assert;

/**
 * 类型集合
 * 
 * @author Administrator
 * 
 */
public class TypesUtils {
	private static final Map<String, Class> clzs = new HashMap<String, Class>();
	// 内部常量，可考虑用XML外部配置
	static {
		clzs.put("int", int.class);
		clzs.put("float",float.class);
		clzs.put("double",double.class);
		clzs.put("long",long.class);
		clzs.put("byte", byte.class);
		clzs.put("short", short.class);
		clzs.put("boolean", boolean.class);
		clzs.put("char", char.class);
		
		clzs.put(Integer.class.getName(), Integer.class);
		clzs.put(Float.class.getName(), Float.class);
		clzs.put(Double.class.getName(), Double.class);
		clzs.put(Long.class.getName(), Long.class);
		clzs.put(Byte.class.getName(), Byte.class);
		clzs.put(Short.class.getName(), Short.class);
		clzs.put(Boolean.class.getName(), Boolean.class);
		clzs.put(Character.class.getName(), Character.class);
		clzs.put(String.class.getName(), String.class);
	}

	private TypesUtils(){}
	
	/**
	 * 注册类型入容器
	 * 
	 * @param clz
	 *            类型
	 */
	public static void registerTypes(Class clz) {
		String clzKey = clz.getName();
		clzs.put(clzKey, clz);
	}

	/**
	 * 注册类型数组入容器
	 * 
	 * @param clzs
	 *            类型数组
	 */
	public static void registerTypes(Class[] clzs) {
		for (Class clz : clzs) {
			registerTypes(clz);
		}
	}
	
	/**
	 * 注册属性文件类型入容器
	 * Type=com.utils.reflect.Types
	 * @param p
	 */
	public static void registerTypes(Properties p){
		
	}

	/**
	 * 注册XML文件类型入容器
	 * <Types>
	 * 	<Type>com.utils.reflect.Types</Type>
	 * </Types>
	 * @param p
	 */
	public static void registerTypes(String xmlPath){
		
	}
	
	/**
	 * 是否原始类型
	 * @param clzName
	 * @return
	 */
	public static boolean isPrimitiveType(String clzName){
		Class realType = toClassType(clzName);
		return realType.isPrimitive();
	}
	
	/**
	 * 转换成Class对象
	 * @param o 传入对象
	 * @return
	 */
	public static Class toClassType(String clzName){
		Class realType = clzs.get(clzName);
		try{
			if (realType == null) {
				realType = Class.forName(clzName);
			}
		}catch (Exception e) {
			e.printStackTrace();
		}
		return realType;
	}
	
	/**
	 * className : "java.lang.Integer"
	 * value : 1
	 * Class.forName("java.lang.Integer") -> 1
	 * @param className
	 * @param val
	 * @return
	 */
	public static Object parseTypeValue(String className,String val){
		Assert.isNotNull(className, "Class name is not allow null.");
		Assert.isNotNull(val, "Class value is not allow null.");
		Class clz  = toClassType(className);
		if (clz == null) {
			throw new IllegalArgumentException("Class parse error.");
		}
		
		clzs.put("int", int.class);
		clzs.put("float",float.class);
		clzs.put("double",double.class);
		clzs.put("long",long.class);
		clzs.put("byte", byte.class);
		clzs.put("short", short.class);
		clzs.put("boolean", boolean.class);
		clzs.put("char", char.class);
		
		if (int.class.equals(clz) || Integer.class.equals(clz)) {
			return Integer.parseInt(val);
		}else if (float.class.equals(clz) || Float.class.equals(clz)) {
			return Float.parseFloat(val);
		}else if (double.class.equals(clz) || Float.class.equals(clz)) {
			return Double.parseDouble(val);
		}else if (long.class.equals(clz) || Long.class.equals(clz)) {
			return Long.parseLong(val);
		}else if(byte.class.equals(clz) || Byte.class.equals(clz)){
			return Byte.parseByte(val);
		}else if(short.class.equals(clz) || Short.class.equals(clz)){
			return Short.parseShort(val);
		}else if(boolean.class.equals(clz) || Boolean.class.equals(clz)){
			return Boolean.parseBoolean(val);
		}else if(char.class.equals(clz) || Character.class.equals(clz)){
			if (val.length() > 1) {
				throw new IllegalArgumentException("Character parse error ,the char's length is "+val.length()+",isn't a char.");
			}
			return val.charAt(0);
		}else if (String.class.equals(clz)) {
			return String.valueOf(val);
		}
		//以后扩展
		//...
		throw new IllegalArgumentException("Not define parse class , type error , please extend by xml.");
	}
	
}
